package com.atguigu.gmall.cart.service.impl;

import com.atguigu.gmall.cart.model.CartInfo;
import com.atguigu.gmall.cart.service.CartService;
import com.atguigu.gmall.common.constant.RedisConst;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.product.client.ProductFeignClient;
import com.atguigu.gmall.product.model.SkuInfo;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author: 小兰
 * @Date: 2023/5/5 18:24
 */
@Service
public class CartServiceImpl implements CartService {
    @Autowired
    private ProductFeignClient productFeignClient;
    @Autowired
    private RedisTemplate redisTemplate;
    /**
     * 将商品放入购物车
     *
     * @param userId
     * @param skuId
     * @param skuNum
     * @return
     */
    @Override
    public void addToCart(String userId, Long skuId, Integer skuNum) {

        //1.远程调用商品微服务获取商品信息
        SkuInfo skuInfo = productFeignClient.getSkuInfo(skuId);
        //2.远程调用商品微服务获取商品价格
        BigDecimal skuPrice = productFeignClient.getSkuPrice(skuId);
        skuInfo.setPrice(skuPrice);
        //3.构建用户购物车hash结构Key
        String cartKey= RedisConst.USER_KEY_PREFIX+userId+RedisConst.USER_CART_KEY_SUFFIX;
        //3.1创建操作hash类型操作对象  绑定某个key
        BoundHashOperations<String,String, CartInfo> hashOps = redisTemplate.boundHashOps(cartKey);
        //4.将用户购物车商品存入Redis 判断商品是否存在
        Boolean aBoolean = hashOps.hasKey(skuId.toString());
        CartInfo cartInfo=null;
        if (aBoolean){
            //4.1存在  购物车商品数量累加
            cartInfo = hashOps.get(skuId.toString());
            cartInfo.setSkuNum(cartInfo.getSkuNum() + skuNum);

        }else {
            //4.2不存在  购物车新增商品
            cartInfo=new CartInfo();
            BeanUtils.copyProperties(skuInfo,cartInfo);
            cartInfo.setUserId(userId);
            cartInfo.setSkuId(skuId);
            cartInfo.setCartPrice(skuPrice);
            cartInfo.setSkuPrice(skuPrice);
            cartInfo.setSkuNum(skuNum);
            cartInfo.setImgUrl(skuInfo.getSkuDefaultImg());
        }
        hashOps.put(skuId.toString(),cartInfo);



    }
//    /**
//     * 初版: 分别查询已登录,或者未登录购物车列表 不考虑合并
//     *
//     * @param userId     登录用户ID
//     * @param userTempId 临时用户ID
//     * @return
//     */
//    @Override
//    public List<CartInfo> getCartList(String userId, String userTempId) {
//        List<CartInfo> loginCartList = null;
//        //1.判断登录用户ID是否有值  查询已登录购物车列表 并且返回
//        if (StringUtils.isNotBlank(userId)) {
//            String redisKey = RedisConst.USER_KEY_PREFIX + userId + RedisConst.USER_CART_KEY_SUFFIX;
//            BoundHashOperations<String, String, CartInfo> loginHashOps = redisTemplate.boundHashOps(redisKey);
//            loginCartList = loginHashOps.values();
//            return loginCartList;
//        }
//
//        //2.判断临时用户ID是否有值  查询未登录购物车列表 并且返回
//        List<CartInfo> noLoginCartList = null;
//        if (StringUtils.isNotBlank(userTempId)) {
//            String redisKey = RedisConst.USER_KEY_PREFIX + userTempId + RedisConst.USER_CART_KEY_SUFFIX;
//            BoundHashOperations<String, String, CartInfo> noLoginHashOps = redisTemplate.boundHashOps(redisKey);
//            noLoginCartList = noLoginHashOps.values();
//            return noLoginCartList;
//        }
//        return null;
//    }

    /**
     * 查询当前用户(登录用户,临时用户)购物车商品列表
     * 合并
     * @param userId
     * @param userTempId
     * @return
     */
    @Override
    public List<CartInfo> getCartList(String userId, String userTempId) {
        List<CartInfo> noLoginCartList = null;
        //判断临时用户ID是否有值  查寻未登录购物车列表 并且返回
        if (StringUtils.isNotBlank(userTempId)){
            String redisKey = RedisConst.USER_KEY_PREFIX+userTempId+RedisConst.USER_CART_KEY_SUFFIX;
            BoundHashOperations<String,String,CartInfo> noLoginHashOps = redisTemplate.boundHashOps(redisKey);
            noLoginCartList = noLoginHashOps.values();
        }
        //1.1如果用户未登录,直接返回未登录购物车列表
        if (StringUtils.isBlank(userId)){
            //1.2对购物车集合进行排序
            noLoginCartList.stream().sorted((o1,o2)->{
                //比较相邻两个购物车对象中创建时间
                return DateUtil.truncatedCompareTo(o1.getCreateTime(),o2.getCreateTime(), Calendar.SECOND);

            }).collect(Collectors.toList());
            return noLoginCartList;
        }
        //2.else,走到这里,就是用户登陆了,,,
        //2.1判断等ID是否有值,查询应景登录的购物车列表,
        String loginRedisKey=RedisConst.USER_KEY_PREFIX+userId+RedisConst.USER_CART_KEY_SUFFIX;
        BoundHashOperations<String, String, CartInfo> loginHashOps = redisTemplate.boundHashOps(loginRedisKey);
        //2.2判断未登录购物车有数据跟当前登录购物车列表合并
        if (!CollectionUtils.isEmpty(noLoginCartList)){
            for (CartInfo noLoginCartInfo : noLoginCartList) {
                String hashKey = noLoginCartInfo.getSkuId().toString();
                if (loginHashOps.hasKey(hashKey)){
                    //包含该商品,,修改数量
                    CartInfo loginCartInfo = loginHashOps.get(hashKey);
                    //跟新数量
                    loginCartInfo.setSkuNum(loginCartInfo.getSkuNum()+noLoginCartInfo.getSkuNum());
                    loginCartInfo.setUpdateTime(new Date());
                    //更新购物车状态
                    loginHashOps.put(hashKey,loginCartInfo);
                }else {
                    //已登录购物车不包含该商品  修改未登录购物车商品中用户ID
                    noLoginCartInfo.setUserId(userId);
                    loginHashOps.put(hashKey,noLoginCartInfo);

                }
            }
        }
        //3.合并以后删除未登录购物车
        String noLogRedisKey=RedisConst.USER_KEY_PREFIX+userTempId+RedisConst.USER_CART_KEY_SUFFIX;
        redisTemplate.delete(noLogRedisKey);

        //4.查询应登陆购物车列表
        List<CartInfo> loginCartList = loginHashOps.values();
        if (!CollectionUtils.isEmpty(loginCartList)) {
            List<CartInfo> cartInfoList = loginCartList.stream().sorted((o1, o2) -> {
                return DateUtil.truncatedCompareTo(o1.getCreateTime(), o2.getCreateTime(), Calendar.SECOND);
            }).collect(Collectors.toList());
            return cartInfoList;
        }

        return null;
    }

    /**
     * 修改购物车商品选中状态
     *
     * @param userId
     * @param skuId
     * @param isChecked
     * @return
     */
    @Override
    public void updateCheck(String userId, Long skuId, int isChecked) {
        String redisKey = RedisConst.USER_KEY_PREFIX+userId+RedisConst.USER_CART_KEY_SUFFIX;
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(redisKey);
        if (hashOps.hasKey(skuId.toString())) {
            CartInfo cartInfo = hashOps.get(skuId.toString());
            cartInfo.setIsChecked(isChecked);
            hashOps.put(skuId.toString(), cartInfo);
        }
    }

    /**
     * 删除购物车中商品
     *
     * @param userId
     * @param skuId
     * @return
     */
    @Override
    public void deleteCart(String userId, Long skuId) {
        String redisKey = RedisConst.USER_KEY_PREFIX+userId+RedisConst.USER_CART_KEY_SUFFIX;
        BoundHashOperations<String,String,CartInfo> hashOps = redisTemplate.boundHashOps(redisKey);
        if (hashOps.hasKey(skuId.toString())){
            hashOps.delete(skuId.toString());
        }

    }

    /**
     * 查询指定用户选中的购物车列表
     *
     * @param userId
     * @return
     */
    @Override
    public List<CartInfo> getCartCheckedList(Long userId) {
        //1.构建用户车hash结构key
        String redisKey=RedisConst.USER_KEY_PREFIX+userId+RedisConst.USER_CART_KEY_SUFFIX;
        BoundHashOperations<String, String, CartInfo> hashOps = redisTemplate.boundHashOps(redisKey);
        List<CartInfo> cartInfoList = hashOps.values();
        //2.查询购物车列表,对购物数据进行过滤,,要选中的,ischeck=1的
        if (!CollectionUtils.isEmpty(cartInfoList)) {
            cartInfoList = cartInfoList.stream().filter(cartInfo -> {
                return cartInfo.getIsChecked().intValue() == 1;
            }).collect(Collectors.toList());
        } if (CollectionUtils.isEmpty(cartInfoList)){
            throw  new RuntimeException("没有需要结算商品!尼龙啊!");
        }
        return cartInfoList;
    }
}
